package com.youkeda.DesertCamel.dao.mapper;

import com.youkeda.DesertCamel.dao.dataobject.MrMeetingRoom;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.ResultType;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.type.JdbcType;

import java.util.List;

@Mapper

public interface MrMeetingRoomMapper {

    @Delete({
            "delete from mr_meeting_room",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    int deleteByPrimaryKey(String id);


    @Insert({
            "insert into mr_meeting_room (id, name, ",
            "code, capacity, ",
            "area, in_maintenance, ",
            "has_computer, has_projector, ",
            "has_screen, has_whiteboard, ",
            "floor, building, ",
            "in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified)",
            "values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, ",
            "#{code,jdbcType=VARCHAR}, #{capacity,jdbcType=INTEGER}, ",
            "#{area,jdbcType=INTEGER}, #{inMaintenance,jdbcType=BIT}, ",
            "#{hasComputer,jdbcType=BIT}, #{hasProjector,jdbcType=BIT}, ",
            "#{hasScreen,jdbcType=BIT}, #{hasWhiteboard,jdbcType=BIT}, ",
            "#{floor,jdbcType=INTEGER}, #{building,jdbcType=INTEGER}, ",
            "#{inUse,jdbcType=BIT}, #{beBooked,jdbcType=BIT}, #{usingTimes,jdbcType=INTEGER}, ",
            "#{gmtCreated,jdbcType=TIMESTAMP}, #{gmtModified,jdbcType=TIMESTAMP})"
    })
    int insert(MrMeetingRoom record);


    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified",
            "from mr_meeting_room",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    @Results(id = "all", value = {
            @Result(column = "id", property = "id", jdbcType = JdbcType.VARCHAR, id = true),
            @Result(column = "name", property = "name", jdbcType = JdbcType.VARCHAR),
            @Result(column = "code", property = "code", jdbcType = JdbcType.VARCHAR),
            @Result(column = "capacity", property = "capacity", jdbcType = JdbcType.INTEGER),
            @Result(column = "area", property = "area", jdbcType = JdbcType.INTEGER),
            @Result(column = "in_maintenance", property = "inMaintenance", jdbcType = JdbcType.BIT),
            @Result(column = "has_computer", property = "hasComputer", jdbcType = JdbcType.BIT),
            @Result(column = "has_projector", property = "hasProjector", jdbcType = JdbcType.BIT),
            @Result(column = "has_screen", property = "hasScreen", jdbcType = JdbcType.BIT),
            @Result(column = "has_whiteboard", property = "hasWhiteboard", jdbcType = JdbcType.BIT),
            @Result(column = "floor", property = "floor", jdbcType = JdbcType.INTEGER),
            @Result(column = "building", property = "building", jdbcType = JdbcType.INTEGER),
            @Result(column = "in_use", property = "inUse", jdbcType = JdbcType.BIT),
            @Result(column = "be_booked", property = "beBooked", jdbcType = JdbcType.BIT),
            @Result(column = "using_times", property = "usingTimes", jdbcType = JdbcType.INTEGER),
            @Result(column = "gmt_created", property = "gmtCreated", jdbcType = JdbcType.TIMESTAMP),
            @Result(column = "gmt_modified", property = "gmtModified", jdbcType = JdbcType.TIMESTAMP)
    })
    MrMeetingRoom selectByPrimaryKey(String id);


    @Update({
            "update mr_meeting_room",
            "set name = #{name,jdbcType=VARCHAR},",
            "code = #{code,jdbcType=VARCHAR},",
            "capacity = #{capacity,jdbcType=INTEGER},",
            "area = #{area,jdbcType=INTEGER},",
            "in_maintenance = #{inMaintenance,jdbcType=BIT},",
            "has_computer = #{hasComputer,jdbcType=BIT},",
            "has_projector = #{hasProjector,jdbcType=BIT},",
            "has_screen = #{hasScreen,jdbcType=BIT},",
            "has_whiteboard = #{hasWhiteboard,jdbcType=BIT},",
            "floor = #{floor,jdbcType=INTEGER},",
            "building = #{building,jdbcType=INTEGER},",
            "in_use = #{inUse,jdbcType=BIT},",
            "be_booked = #{beBooked,jdbcType=BIT},",
            "using_times = #{usingTimes,jdbcType=INTEGER},",
            "gmt_created = #{gmtCreated,jdbcType=TIMESTAMP},",
            "gmt_modified = #{gmtModified,jdbcType=TIMESTAMP}",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    int updateByPrimaryKey(MrMeetingRoom record);

    /**
     * 通过会议室名称获取会议室所有信息
     *
     * @param name 会议室名称
     * @return 会议室所有信息
     */
    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified",
            "from mr_meeting_room",
            "where name = #{name,jdbcType=VARCHAR}"
    })
    @ResultMap("all")
    MrMeetingRoom selectByMeetingname(String name);

    /**
     * 通过会议室代号获取会议室所有信息
     *
     * @param code 会议室代号
     * @return 会议室所有信息
     */
    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified",
            "from mr_meeting_room",
            "where code = #{code,jdbcType=VARCHAR}"
    })
    @ResultMap("all")
    MrMeetingRoom selectByMeetingcode(String code);

    /**
     * 通过用户筛选的会议室要求查询距离最近的所有会议室,按距离优先排序
     *
     * @param searchParam 用户要求的会议室配置要求信息
     * @return 所有符合要求的会议室的信息
     */
    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified,",
            "if(building = #{building,jdbcType=INTEGER}, if(floor - #{floor,jdbcType=INTEGER} >= 0, " +
                    "floor - #{floor,jdbcType=INTEGER}, #{floor,jdbcType=INTEGER} - floor),floor) " +
                    "as floor_disance",
            "from mr_meeting_room",
            "inner join mr_distance as D",
            "on D.end = building && D.start = #{building,jdbcType=INTEGER}",
            "where capacity >= " +
                    "#{capacity,jdbcType=INTEGER} " +
                    "and in_maintenance = false " +
                    "and be_booked = false " +
                    "and in_use = false " +
                    "and if(#{hasComputer,jdbcType=BIT} = true,has_computer = " +
                    "#{hasComputer,jdbcType=BIT},1) and if(#{hasProjector,jdbcType=BIT} = true," +
                    "has_projector = #{hasProjector,jdbcType=BIT},1) and if(#{hasScreen,jdbcType=BIT} = true," +
                    "has_screen = #{hasScreen,jdbcType=BIT},1) and if(#{hasWhiteboard,jdbcType=BIT} = true," +
                    "has_whiteboard = #{hasWhiteboard,jdbcType=BIT},1)",
            "order by D.distance asc,floor_disance asc,capacity asc"
    })
    @ResultMap("all")
    List<MrMeetingRoom> selectSortedByDistanceNotLimited(MrMeetingRoom searchParam);


    /**
     * 通过用户筛选的会议室要求查询距离最近的所有会议室,按人数优先排序
     *
     * @param searchParam 用户要求的会议室配置要求信息
     * @return 所有符合要求的会议室的信息
     */
    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified,",
            "if(building = #{building,jdbcType=INTEGER}, if(floor - #{floor,jdbcType=INTEGER} >= 0, " +
                    "floor - #{floor,jdbcType=INTEGER}, #{floor,jdbcType=INTEGER} - floor),floor) " +
                    "as floor_disance",
            "from mr_meeting_room",
            "inner join mr_distance as D",
            "on D.end = building && D.start = #{building,jdbcType=INTEGER}",
            "where capacity >= " +
                    "#{capacity,jdbcType=INTEGER} " +
                    "and in_maintenance = false " +
                    "and be_booked = false " +
                    "and in_use = false " +
                    "and if(#{hasComputer,jdbcType=BIT} = true,has_computer = " +
                    "#{hasComputer,jdbcType=BIT},1) and if(#{hasProjector,jdbcType=BIT} = true," +
                    "has_projector = #{hasProjector,jdbcType=BIT},1) and if(#{hasScreen,jdbcType=BIT} = true," +
                    "has_screen = #{hasScreen,jdbcType=BIT},1) and if(#{hasWhiteboard,jdbcType=BIT} = true," +
                    "has_whiteboard = #{hasWhiteboard,jdbcType=BIT},1)",
            "order by capacity asc,D.distance asc,floor_disance asc"
    })
    @ResultMap("all")
    List<MrMeetingRoom> selectSortedByCapacityNotLimited(MrMeetingRoom searchParam);


    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified,",
            "if(building = #{searchParam.building,jdbcType=INTEGER}, " +
                    "if(floor - #{searchParam.floor,jdbcType=INTEGER} >= 0, " +
                    "floor - #{searchParam.floor,jdbcType=INTEGER}, #{searchParam.floor,jdbcType=INTEGER} - floor),floor) " +
                    "as floor_disance",
            "from mr_meeting_room",
            "inner join mr_distance as D",
            "on D.end = building && D.start = #{searchParam.building,jdbcType=INTEGER}",
            "where capacity >= " +
                    "#{searchParam.capacity,jdbcType=INTEGER} " +
                    "and in_maintenance = false " +
                    "and be_booked = false " +
                    "and in_use = false " +
                    "and if(#{searchParam.hasComputer,jdbcType=BIT} = true,has_computer = " +
                    "#{searchParam.hasComputer,jdbcType=BIT},1) and if(#{searchParam.hasProjector,jdbcType=BIT} = true," +
                    "has_projector = #{searchParam.hasProjector,jdbcType=BIT},1) and if(#{searchParam.hasScreen,jdbcType=BIT} = true," +
                    "has_screen = #{searchParam.hasScreen,jdbcType=BIT},1) and if(#{searchParam.hasWhiteboard,jdbcType=BIT} = true," +
                    "has_whiteboard = #{searchParam.hasWhiteboard,jdbcType=BIT},1)",
            "order by D.distance asc,floor_disance asc,capacity asc",
            "limit #{startPage,jdbcType=INTEGER},#{pageSize,jdbcType=INTEGER}"
    })
    @ResultMap("all")
    List<MrMeetingRoom> selectSortedByDistanceLimited(MrMeetingRoom searchParam, int startPage, int pageSize);

    @Select({
            "select",
            "id, name, code, capacity, area, in_maintenance, has_computer, has_projector, ",
            "has_screen, has_whiteboard, floor, building, in_use, be_booked, using_times, ",
            "gmt_created, gmt_modified,",
            "if(building = #{searchParam.building,jdbcType=INTEGER}, if(floor - #{searchParam.floor,jdbcType=INTEGER} >= 0, " +
                    "floor - #{searchParam.floor,jdbcType=INTEGER}, #{searchParam.floor,jdbcType=INTEGER} - floor),floor) " +
                    "as floor_disance",
            "from mr_meeting_room",
            "inner join mr_distance as D",
            "on D.end = building && D.start = #{searchParam.building,jdbcType=INTEGER}",
            "where capacity >= " +
                    "#{searchParam.capacity,jdbcType=INTEGER} " +
                    "and in_maintenance = false " +
                    "and be_booked = false " +
                    "and in_use = false " +
                    "and if(#{searchParam.hasComputer,jdbcType=BIT} = true,has_computer = " +
                    "#{searchParam.hasComputer,jdbcType=BIT},1) and if(#{searchParam.hasProjector,jdbcType=BIT} = true," +
                    "has_projector = #{searchParam.hasProjector,jdbcType=BIT},1) and if(#{searchParam.hasScreen,jdbcType=BIT} = true," +
                    "has_screen = #{searchParam.hasScreen,jdbcType=BIT},1) and if(#{searchParam.hasWhiteboard,jdbcType=BIT} = true," +
                    "has_whiteboard = #{searchParam.hasWhiteboard,jdbcType=BIT},1)",
            "order by capacity asc ,D.distance asc,floor_disance asc",
            "limit #{startPage,jdbcType=INTEGER},#{pageSize,jdbcType=INTEGER}"
    })
    @ResultMap("all")
    List<MrMeetingRoom> selectSortedByCapacityLimited(MrMeetingRoom searchParam, int startPage, int pageSize);


    /**
     * 通过会议室id(主键)和使用次数修改被使用次数
     * 先获取对象会议室原来的被使用次数,在服务层加1后再传回对象,再修改
     * @param id 会议室id(主键)
     * @param usingTimes 使用次数
     * @return 是否成功
     */
    @Update({
            "update mr_meeting_room",
            "set using_times = #{usingTimes,jdbcType=INTEGER}",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    int updateTimesByMeeting(String id, int usingTimes);


    /**
     * 通过主键和是否被预定值修改是否被预定
     *
     * @param id       id
     * @param beBooked 是否被预定
     * @return 是否成功
     */
    @Update({
            "update mr_meeting_room",
            "set be_booked = #{beBooked,jdbcType=BIT}",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    int updateBookedByPrimaryKey(String id, boolean beBooked);

    /**
     * 通过主键和是否在使用中修改是否在使用中
     *
     * @param id    主键
     * @param inUse 是否在使用中
     * @return 是否成功
     */
    @Update({
            "update mr_meeting_room",
            "set in_use = #{inUse,jdbcType=BIT}",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    int updateUseByPrimaryKey(String id, boolean inUse);

    /**
     * 通过主键查询使用次数
     *
     * @param id 主键
     * @return 使用次数
     */
    @Select({
            "select",
            "using_times",
            "from mr_meeting_room",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    @Results({
            @Result(column = "using_times", property = "usingTimes", jdbcType = JdbcType.INTEGER),
    })
    MrMeetingRoom selectTimesByPrimaryKey(String id);

    /**
     * 通过主键查询会议室名称
     * @param id 主键
     * @return 会议室名称
     */
    @Select({
            "select",
            "name",
            "from mr_meeting_room",
            "where id = #{id,jdbcType=VARCHAR}"
    })
    @ResultType(String.class)
    String selectMeetingRoomNameByPrimaryKey(String id);
}

